import React, {
  PropsWithChildren,
  ReactNode,
  useMemo,
  createContext,
  useState,
  useEffect,
  useRef,
  useContext,
} from 'react'

const Context = createContext({})

export function AliveScope(props: any) {
  const [state, setState] = useState({})
  // 存放渲染之后的dom
  const ref: any = useMemo(() => {
    return {}
  }, [])

  const keep = useMemo(() => {
    return (id: any, children: any) =>
      new Promise((resolve) => {
        // 这里的children是虚拟 节点
        setState((pre) => ({ ...pre, [id]: { id, children } }))
        setTimeout(() => {
          //需要等待setState渲染完拿到实例返回给子组件。
          // 将渲染过的dom节点 返回给keep-alive组件
          resolve(ref[id])
        })
      })
  }, [ref])
  debugger
  return (
    <Context.Provider value={keep}>
      {props.children}
      {/* keepAlive节点的children实际是在父组件渲染的 */}
      {Object.values(state).map((v: any, i: number) => (
        <div key={v.id} ref={(node) => (ref[v.id] = node)}>
          {v.children}
        </div>
      ))}
    </Context.Provider>
  )
}

type KeepAliveProps = {
  id: string
}

export function KeepAlive(props: PropsWithChildren<KeepAliveProps>) {
  const keep: any = useContext(Context)
  const ref: any = useRef(null)

  useEffect(() => {
    debugger
    const init = async (data: any) => {
      // 获取真实dom节点
      const realContent = await keep(data.id, data.children)
      if (ref.current) {
        // 真实dom挂载到 节点上
        ref.current.appendChild(realContent)
      }
    }
    init(props)
  }, [props, keep])
  return <div ref={ref}></div>
}
